package com.dfbz.demo02_注解的解析;

import com.dfbz.anno.Coder;
import com.dfbz.anno.Computer;
import com.dfbz.anno.Phone;
import com.dfbz.anno.Student;
import org.junit.Test;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
public class Demo01_注解的解析 {

    /**
     * 解析类上面的注解
     *
     * @throws Exception
     */
    @Test
    public void test1() throws Exception {

        // 1. 先获取字节码对象
        Class<TestComputer> computerClass = TestComputer.class;

        // 2. 通过字节码对象获取标注在类上面的注解
        Computer computer = computerClass.getAnnotation(Computer.class);
        Phone phone = computerClass.getAnnotation(Phone.class);

        // 3. 打印注解信息
        System.out.println(computer.value());
        System.out.println(computer.price());
        System.out.println(Arrays.toString(computer.factories()));

        System.out.println("----------");

        System.out.println(phone.value());
    }

    /**
     * 解析构造方法上的注解
     *
     * @throws Exception
     */
    @Test
    public void test2() throws Exception {

        // 1. 先获取字节码对象
        Class<TestComputer> computerClass = TestComputer.class;

        // 2. 通过字节码对象获取指定的构造器
        Constructor<TestComputer> constructor = computerClass.getConstructor();

        // 3. 通过constructor获取构造器上标注的注解
        Computer computer = constructor.getAnnotation(Computer.class);

        // 3. 打印注解信息
        System.out.println(computer.value());
        System.out.println(computer.price());
        System.out.println(Arrays.toString(computer.factories()));
    }


    /**
     * 解析方法上的注解
     *
     * @throws Exception
     */
    @Test
    public void test3() throws Exception {

        // 1. 先获取字节码对象
        Class<TestComputer> computerClass = TestComputer.class;

        // 2. 通过字节码对象获取指定的方法
        Method method = computerClass.getMethod("print");

        // 3. 通过method获取方法上标注的注解
        Computer computer = method.getAnnotation(Computer.class);

        // 3. 打印注解信息
        System.out.println(computer.value());
        System.out.println(computer.price());
        System.out.println(Arrays.toString(computer.factories()));
    }


    /**
     * 解析成员变量上的注解
     *
     * @throws Exception
     */
    @Test
    public void test4() throws Exception {

        // 1. 先获取字节码对象
        Class<TestComputer> computerClass = TestComputer.class;

        // 2. 通过字节码对象获取指定的方法
        Field field = computerClass.getField("name");

        // 3. 通过field获取成员变量上标注的注解
        Computer computer = field.getAnnotation(Computer.class);

        // 3. 打印注解信息
        System.out.println(computer.value());
        System.out.println(computer.price());
        System.out.println(Arrays.toString(computer.factories()));
    }

/**
 * 解析注解的其他方法
 *
 * @throws Exception
 */
@Test
public void test5() throws Exception {

    // 1. 先获取字节码对象
    Class<TestComputer> computerClass = TestComputer.class;

    // true
    System.out.println(computerClass.isAnnotationPresent(Computer.class));

    // true
    System.out.println(computerClass.isAnnotationPresent(Phone.class));

    // false(即使在TestComputer对象上标注了Student注解,也要让Student注解的生命周期为RUNTIME)
    System.out.println(computerClass.isAnnotationPresent(Student.class));

    // false(即使在TestComputer对象上标注了Coder注解,也要让Coder注解的生命周期为RUNTIME)
    System.out.println(computerClass.isAnnotationPresent(Coder.class));

    // 获取TestComputer上标注的所有注解(包括TestComputer父类的注解)
    Annotation[] annotations = computerClass.getAnnotations();
    for (Annotation annotation : annotations) {
        System.out.println(annotation);
    }

    System.out.println("-------------------------");
}
}
